package per.zqx.msrw.aspects;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import per.zqx.msrw.config.DBContextHolder;

/**
 * DataSourceAspect, 数据源动态切换切面
 *
 * @author Sa, Zhang 2021-12-28 14:32
 */

@Aspect
@Component
@Order(0) // 配置注解优先级，优于事物注解@Transactional先进行数据源切换，不然在事物中进行数据源切换无效
public class DataSourceAspect {

    /**
     * 写操作切点
     */
    @Pointcut("@annotation(per.zqx.msrw.annos.Master)" +
            "|| execution(* per.zqx.msrw.service.impl..insert*(..)) " +
            "|| execution(* per.zqx.msrw.service.impl..add*(..)) " +
            "|| execution(* per.zqx.msrw.service.impl..update*(..)) " +
            "|| execution(* per.zqx.msrw.service.impl..delete*(..)) " +
            "|| execution(* per.zqx.msrw.service.impl..save*(..))")
    public void writePointCut() {
    }

    /**
     * 未加Master注解的，读操作切点
     */
    @Pointcut("!@annotation(per.zqx.msrw.annos.Master)" +
            "&& (@annotation(per.zqx.msrw.annos.Slave) " +
            "|| execution(* per.zqx.msrw.service.impl..get*(..)) " +
            "|| execution(* per.zqx.msrw.service.impl..list*(..)) " +
            "|| execution(* per.zqx.msrw.service.impl..find*(..)) " +
            "|| execution(* per.zqx.msrw.service.impl..select*(..)))")
    public void readPointCut() {
    }

    /**
     * 切换上下文
     */
    @Before("readPointCut()")
    public void read() {
        DBContextHolder.slave();
    }

    /**
     * 切换上下文
     */
    @Before("writePointCut()")
    public void write() {
        DBContextHolder.master();
    }

}
